<template>
  <el-form-item
    :label="label"
    :label-width="labelWidth"
    :prop="props.data.field"
    :required="props.data.required"
    :rules="props.data.rules"
    class="upload-file"
  >
    <el-upload
      v-model:file-list="fileList"
      :action="uploadAction"
      :headers="uploadHeaders"
      :accept="accept"
      :multiple="props.data.multiple"
      :limit="props.data.limit"
      :list-type="props.data.listType"
      :before-upload="onBeforeUpload"
      :on-preview="handlePreview"
      :on-exceed="handleExceed"
      :disabled="props.data.disabled"
    >
      <el-button type="primary" plain size="small" :icon="Upload" :disabled="props.data.disabled">
        {{ props.data.text }}
      </el-button>
      <template #tip v-if="props.data.tip && props.data.fileSize">
        <div class="el-upload__tip">文件大小不能超过{{ props.data.fileSize }}MB.</div>
      </template>
    </el-upload>
    <el-image-viewer @close="imgVisible = false" :url-list="imgList" v-if="imgVisible" />
  </el-form-item>
</template>
<script lang="ts" setup>
import { ref, computed } from 'vue'
import { ElFormItem, ElMessage, ElUpload, ElImageViewer } from 'element-plus'
import { Upload } from '@element-plus/icons-vue'
import type { UploadProps, UploadUserFile } from 'element-plus'
import { env, header, util } from '@/utils'
import { useProps } from '../../common-props/hooks'

const props = defineProps<{ data: Record<string, any>; form: Record<string, any> }>()
const { label, labelWidth } = useProps(props)

const imgVisible = ref(false)
const fileList = ref<UploadUserFile[]>([])
const imgList = computed(() => {
  return fileList.value
    .filter(f => {
      const resp = f.response as any
      return resp && resp.data && util.imgSuffix().indexOf(resp.data.suffix) >= 0
    })
    .map(f => {
      const resp = f.response as any
      return resp.data.publicUrl
    })
})

const uploadAction = computed(() => `${env.API_DOMAIN}/file/temp/upload`)
const uploadHeaders = computed(() => Object.assign(header.getAuthorization()))

const accept = computed(() => {
  if (props.data.fileType && props.data.fileType.length > 0) {
    return props.data.fileType.join(',')
  } else {
    return undefined
  }
})

const onBeforeUpload = (file: any) => {
  let isRightSize = file.size / 1024 / 1024 < props.data.fileSize
  if (!isRightSize) {
    ElMessage.error(`文件大小超过 ${props.data.fileSize}MB`)
    return false
  }
  let isAccept = true
  const fileType = props.data.fileType
  if (fileType && fileType.length > 0) {
    for (let f = 0; f < fileType.length; f++) {
      let isAccept = new RegExp(fileType[f]).test(file.type)
      if (!isAccept) {
        ElMessage.error(`不可上传[${file.type}]类型文件`)
        isAccept = false
        break
      }
    }
    return isAccept
  }
  return true
}

const handlePreview: UploadProps['onPreview'] = () => {
  if (imgList.value.length > 0) {
    imgVisible.value = true
  }
}

const handleExceed: UploadProps['onExceed'] = () => {
  ElMessage.error(`上传文件不可超过 ${props.data.limit} 个`)
}
</script>

<style lang="scss" scoped>
.el-upload__tip {
  display: inline;
  margin-left: 10px;
  color: $--color-text-secondary;
  font-style: italic;
}
.upload-file {
  :deep(.el-form-item__content) {
    display: block !important;
    margin-top: 5px;
    line-height: 1.6;
  }
  :deep(.el-upload-list__item-info) {
    margin-left: 0;
  }
  :deep(.el-upload-list__item-name) {
    padding-left: 0;
  }
}
</style>
